using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Linq;
using System.Net.Http.Headers;

namespace RestfulApi.Controllers
{
    /// <summary>
    /// 文件管理控制器 - 处理文件上传、下载和管理
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class FilesController : ControllerBase
    {
        // 文件存储的根目录
        private readonly string _uploadsFolder;
        // 允许的文件扩展名
        private readonly string[] _allowedExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".txt" };
        // 最大文件大小 (10MB)
        private readonly long _fileSizeLimit = 10 * 1024 * 1024;

        public FilesController()
        {
            // 设置上传文件的存储路径
            _uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");
            
            // 确保上传目录存在
            if (!Directory.Exists(_uploadsFolder))
            {
                Directory.CreateDirectory(_uploadsFolder);
            }
        }

        /// <summary>
        /// 上传单个文件
        /// </summary>
        /// <returns>上传结果</returns>
        [HttpPost("upload")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> UploadFile([FromForm] IFormFile file)
        {
            // 检查文件是否为空
            if (file == null)
            {
                return BadRequest(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "file", new[] { "The file field is required." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                    title = "One or more validation errors occurred.",
                    status = 400
                });
            }

            // 检查文件内容是否为空
            if (file.Length == 0)
            {
                return BadRequest(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "file", new[] { "The file cannot be empty." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                    title = "One or more validation errors occurred.",
                    status = 400
                });
            }

            // 验证文件大小
            if (file.Length > _fileSizeLimit)
            {
                return BadRequest(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "file", new[] { $"The file size exceeds the limit of {_fileSizeLimit / 1024 / 1024}MB." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                    title = "One or more validation errors occurred.",
                    status = 400
                });
            }

            // 获取文件扩展名并验证
            var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
            if (!_allowedExtensions.Contains(extension))
            {
                return BadRequest(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "file", new[] { $"Unsupported file type. Allowed types: {string.Join(", ", _allowedExtensions)}" } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                    title = "One or more validation errors occurred.",
                    status = 400
                });
            }

            // 创建唯一的文件名
            var uniqueFileName = $"{Guid.NewGuid()}{extension}";
            var filePath = Path.Combine(_uploadsFolder, uniqueFileName);

            // 保存文件
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            // 返回文件信息
            return Ok(new
            {
                fileName = uniqueFileName,
                originalName = file.FileName,
                fileSize = file.Length,
                contentType = file.ContentType,
                downloadUrl = $"/api/files/download/{uniqueFileName}"
            });
        }

        /// <summary>
        /// 上传多个文件
        /// </summary>
        /// <returns>上传结果</returns>
        [HttpPost("upload-multiple")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> UploadMultipleFiles([FromForm] List<IFormFile> files)
        {
            if (files == null || !files.Any())
            {
                return BadRequest(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "files", new[] { "At least one file must be provided." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                    title = "One or more validation errors occurred.",
                    status = 400
                });
            }

            var uploadResults = new List<object>();
            var failedUploads = new List<string>();

            foreach (var file in files)
            {
                // 验证文件大小
                if (file.Length > _fileSizeLimit)
                {
                    failedUploads.Add($"{file.FileName}: 文件大小超过限制");
                    continue;
                }

                // 获取文件扩展名并验证
                var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
                if (!_allowedExtensions.Contains(extension))
                {
                    failedUploads.Add($"{file.FileName}: 不支持的文件类型");
                    continue;
                }

                // 创建唯一的文件名
                var uniqueFileName = $"{Guid.NewGuid()}{extension}";
                var filePath = Path.Combine(_uploadsFolder, uniqueFileName);

                // 保存文件
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                // 添加到成功结果列表
                uploadResults.Add(new
                {
                    fileName = uniqueFileName,
                    originalName = file.FileName,
                    fileSize = file.Length,
                    contentType = file.ContentType,
                    downloadUrl = $"/api/files/download/{uniqueFileName}"
                });
            }

            return Ok(new
            {
                successCount = uploadResults.Count,
                failedCount = failedUploads.Count,
                successFiles = uploadResults,
                failedFiles = failedUploads
            });
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>文件流</returns>
        [HttpGet("download/{fileName}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public IActionResult DownloadFile(string fileName)
        {
            // 构建文件路径
            var filePath = Path.Combine(_uploadsFolder, fileName);

            // 检查文件是否存在
            if (!System.IO.File.Exists(filePath))
            {
                return NotFound(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "fileName", new[] { "The specified file does not exist." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                    title = "Resource not found.",
                    status = 404
                });
            }

            // 读取文件
            var fileBytes = System.IO.File.ReadAllBytes(filePath);

            // 尝试确定内容类型
            var contentType = "application/octet-stream"; // 默认
            var extension = Path.GetExtension(fileName).ToLowerInvariant();
            
            // 根据扩展名设置内容类型
            switch (extension)
            {
                case ".jpg":
                case ".jpeg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    contentType = "image/png";
                    break;
                case ".gif":
                    contentType = "image/gif";
                    break;
                case ".pdf":
                    contentType = "application/pdf";
                    break;
                case ".doc":
                case ".docx":
                    contentType = "application/msword";
                    break;
                case ".xls":
                case ".xlsx":
                    contentType = "application/vnd.ms-excel";
                    break;
                case ".txt":
                    contentType = "text/plain";
                    break;
            }

            // 返回文件
            return File(fileBytes, contentType, Path.GetFileName(filePath));
        }

        /// <summary>
        /// 获取文件列表
        /// </summary>
        /// <returns>文件列表</returns>
        [HttpGet("list")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult ListFiles()
        {
            // 获取目录中的所有文件
            var files = Directory.GetFiles(_uploadsFolder)
                .Select(filePath => new
                {
                    fileName = Path.GetFileName(filePath),
                    fileSize = new FileInfo(filePath).Length,
                    contentType = GetContentType(Path.GetExtension(filePath)),
                    createdDate = System.IO.File.GetCreationTime(filePath),
                    downloadUrl = $"/api/files/download/{Path.GetFileName(filePath)}"
                })
                .OrderByDescending(f => f.createdDate)
                .ToList();

            return Ok(new
            {
                totalCount = files.Count,
                files = files
            });
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>删除结果</returns>
        [HttpDelete("delete/{fileName}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public IActionResult DeleteFile(string fileName)
        {
            // 构建文件路径
            var filePath = Path.Combine(_uploadsFolder, fileName);

            // 检查文件是否存在
            if (!System.IO.File.Exists(filePath))
            {
                return NotFound(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "fileName", new[] { "The specified file does not exist." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                    title = "Resource not found.",
                    status = 404
                });
            }

            try
            {
                // 删除文件
                System.IO.File.Delete(filePath);
                return Ok(new { message = "File deleted successfully", fileName = fileName });
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, 
                    new { 
                        errors = new Dictionary<string, string[]>
                        {
                            { "server", new[] { "An error occurred while deleting the file." } }
                        },
                        type = "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                        title = "Internal Server Error",
                        status = 500,
                        detail = ex.Message
                    });
            }
        }

        /// <summary>
        /// 获取文件信息
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>文件信息</returns>
        [HttpGet("info/{fileName}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public IActionResult GetFileInfo(string fileName)
        {
            // 构建文件路径
            var filePath = Path.Combine(_uploadsFolder, fileName);

            // 检查文件是否存在
            if (!System.IO.File.Exists(filePath))
            {
                return NotFound(new
                {
                    errors = new Dictionary<string, string[]>
                    {
                        { "fileName", new[] { "The specified file does not exist." } }
                    },
                    type = "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                    title = "Resource not found.",
                    status = 404
                });
            }

            // 获取文件信息
            var fileInfo = new FileInfo(filePath);
            
            return Ok(new
            {
                fileName = fileInfo.Name,
                fileSize = fileInfo.Length,
                contentType = GetContentType(fileInfo.Extension),
                createdDate = fileInfo.CreationTime,
                lastModified = fileInfo.LastWriteTime,
                downloadUrl = $"/api/files/download/{fileName}"
            });
        }

        /// <summary>
        /// 根据扩展名获取内容类型
        /// </summary>
        private string GetContentType(string extension)
        {
            switch (extension.ToLowerInvariant())
            {
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".png":
                    return "image/png";
                case ".gif":
                    return "image/gif";
                case ".pdf":
                    return "application/pdf";
                case ".doc":
                case ".docx":
                    return "application/msword";
                case ".xls":
                case ".xlsx":
                    return "application/vnd.ms-excel";
                case ".txt":
                    return "text/plain";
                default:
                    return "application/octet-stream";
            }
        }
    }
}